package jmine.tec.web.servlet.filter.resolver;

import java.io.Serializable;

import javax.servlet.http.HttpServletRequest;

import jmine.tec.utils.spring.InstanceResolver;

/**
 * @author takeshi
 * @param <E> e
 */
public class HttpAttributeInstanceResolver<E> implements InstanceResolver<E>, Serializable {

    private static final long serialVersionUID = 1L;

    private final InstanceResolver<HttpServletRequest> requestResolver;

    private String attributeName;

    private InstanceResolver<E> delegateInstanceResolver;

    private boolean storeInSession;

    /**
     * @return the storeInSession
     */
    public boolean isStoreInSession() {
        return this.storeInSession;
    }

    /**
     * If <code>true</code>, the object will be stored in the session after retrieving from the request or the delegate instance resolver.
     * Else, the object will be stored in the request itself to avoid recreation if in the same request.p
     * 
     * @param storeInSession the storeInSession to set
     */
    public void setStoreInSession(final boolean storeInSession) {
        this.storeInSession = storeInSession;
    }

    /**
     * @param requestResolver the {@link InstanceResolver} to use
     */
    public HttpAttributeInstanceResolver(final InstanceResolver<HttpServletRequest> requestResolver) {
        super();
        this.requestResolver = requestResolver;
    }

    /**
     * @return the attributeName
     */
    public String getAttributeName() {
        return this.attributeName;
    }

    /**
     * @param attributeName the attributeName to set
     */
    public void setAttributeName(final String attributeName) {
        this.attributeName = attributeName;
    }

    /**
     * 
     */
    public void clear() {
    }

    /**
     * 
     */
    public void clearCurrentInstance() {
    }

    /**
     * @return {@link HttpServletRequest}
     */
    private HttpServletRequest getRequest() {
        return this.requestResolver.getInstance();
    }

    /**
     * @return E
     */
    @SuppressWarnings("unchecked")
    public E getInstance() {
        if ((this.requestResolver == null) || (this.attributeName == null)) {
            throw new NullPointerException("null");
        }
        HttpServletRequest req = this.getRequest();
        Object instance = req.getAttribute(this.getAttributeName());
        if (instance != null) {
            return (E) instance;
        }
        instance = req.getSession().getAttribute(this.getAttributeName());
        if (instance != null) {
            return (E) instance;
        }
        instance = req.getSession().getServletContext().getAttribute(this.getAttributeName());
        if ((instance == null) && (this.delegateInstanceResolver != null)) {
            instance = this.delegateInstanceResolver.getInstance();
        }
        if (instance != null) {
            if (this.isStoreInSession()) {
                req.getSession().setAttribute(this.attributeName, instance);
            } else {
                req.setAttribute(this.attributeName, instance);
            }
        }
        return (E) instance;
    }

    /**
     * @param object E
     */
    public void setInstance(final E object) {
    }

    /**
     * @return the delegateInstanceResolver
     */
    public InstanceResolver<E> getDelegateInstanceResolver() {
        return this.delegateInstanceResolver;
    }

    /**
     * @param delegateInstanceResolver the delegateInstanceResolver to set
     */
    public void setDelegateInstanceResolver(final InstanceResolver<E> delegateInstanceResolver) {
        this.delegateInstanceResolver = delegateInstanceResolver;
    }

}
